
/**
  ******************************************************************************
  * Copyright 2021 The grapilot Authors. All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * 
  * http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * 
  * @file       notify_device.h
  * @author     baiyang
  * @date       2022-1-16
  ******************************************************************************
  */

#pragma once

#ifdef __cplusplus
extern "C"{
#endif

/*----------------------------------include-----------------------------------*/
#include <stdint.h>
#include <rtdebug.h>

#include <mavproxy/mavproxy.h>
/*-----------------------------------macro------------------------------------*/

/*----------------------------------typedef-----------------------------------*/
typedef struct notify_device* notify_device_t;
typedef struct notify_device_ops* notify_device_ops_t;

/** @ 
  * @brief  
  */
struct notify_device_ops {
    void (*NotifyDeviceDestructor)(notify_device_t notify_dev);

    // init - initialised the device
    bool (*init)(notify_device_t notify_dev);

    // update - updates device according to timed_updated.  Should be
    // called at 50Hz
    void (*update)(notify_device_t notify_dev);

    // handle a LED_CONTROL message, by default device ignore message
    void (*handle_led_control)(notify_device_t notify_dev, const mavlink_message_t *msg);

    // handle a PLAY_TUNE message, by default device ignore message
    void (*handle_play_tune)(notify_device_t notify_dev, const mavlink_message_t *msg);

    // play a MML tune
    void (*play_tune)(notify_device_t notify_dev, const char *tune);

    // RGB control
    // give RGB and flash rate, used with scripting
    void (*rgb_control)(notify_device_t notify_dev, uint8_t r, uint8_t g, uint8_t b, uint8_t rate_hz);

    // RGB control multiple leds independently
    // give RGB value for single led
    void (*rgb_set_id)(notify_device_t notify_dev, uint8_t r, uint8_t g, uint8_t b, uint8_t id);
};

/** @ 
  * @brief  
  */
struct notify_device {
    // this pointer is used to read the parameters relative to devices
    void *pNotify;

    notify_device_ops_t ops;
};

/*----------------------------------variable----------------------------------*/

/*-------------------------------------os-------------------------------------*/

/*----------------------------------function----------------------------------*/
static inline void NotifyDeviceDestructor(notify_device_t notify_dev) {
    if (notify_dev->ops->NotifyDeviceDestructor) {
        notify_dev->ops->NotifyDeviceDestructor(notify_dev);
    }
}

// init - initialised the device
static inline bool notify_device_init(notify_device_t notify_dev) {
    RT_ASSERT(notify_dev != RT_NULL);
    RT_ASSERT(notify_dev->ops->init != RT_NULL);

    return notify_dev->ops->init(notify_dev);
}

// update - updates device according to timed_updated.  Should be
// called at 50Hz
static inline void notify_device_update(notify_device_t notify_dev) {
    RT_ASSERT(notify_dev != RT_NULL);
    RT_ASSERT(notify_dev->ops->update != RT_NULL);

    notify_dev->ops->update(notify_dev);
}

// handle a LED_CONTROL message, by default device ignore message
static inline void notify_device_handle_led_control(notify_device_t notify_dev, const mavlink_message_t *msg) {
    if (notify_dev->ops->handle_led_control) {
        notify_dev->ops->handle_led_control(notify_dev, msg);
    }
}

// handle a PLAY_TUNE message, by default device ignore message
static inline void notify_device_handle_play_tune(notify_device_t notify_dev, const mavlink_message_t *msg) {
    if (notify_dev->ops->handle_play_tune) {
        notify_dev->ops->handle_play_tune(notify_dev, msg);
    }
}

// play a MML tune
static inline void notify_device_play_tune(notify_device_t notify_dev, const char *tune) {
    if (notify_dev->ops->play_tune) {
        notify_dev->ops->play_tune(notify_dev, tune);
    }
}

// RGB control
// give RGB and flash rate, used with scripting
static inline void notify_device_rgb_control(notify_device_t notify_dev, uint8_t r, uint8_t g, uint8_t b, uint8_t rate_hz) {
    if (notify_dev->ops->rgb_control) {
        notify_dev->ops->rgb_control(notify_dev, r, g, b, rate_hz);
    }
}

// RGB control multiple leds independently
// give RGB value for single led
static inline void notify_device_rgb_set_id(notify_device_t notify_dev, uint8_t r, uint8_t g, uint8_t b, uint8_t id) {
    if (notify_dev->ops->rgb_set_id) {
        notify_dev->ops->rgb_set_id(notify_dev, r, g, b, id);
    }
}

/*------------------------------------test------------------------------------*/

#ifdef __cplusplus
}
#endif



